package com.draemoncode.weixindb.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

/**
 * <p></p>
 *
 * @author  yangz
 * @date    2016/11/7
 * @version latest
 */
public class JSONUtil {

    private static ObjectMapper mapper;

    static {
        mapper = new ObjectMapper();
        //设置时区
        mapper.setTimeZone(TimeZone.getDefault());
        // 设置时间为 ISO-8601 日期
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
        mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        //设定是否使用Enum的toString函数来读取Enum, 为False时使用Enum的name()函数来读取Enum,
        mapper.configure(DeserializationFeature.READ_ENUMS_USING_TO_STRING, true);
        // 如果输入不存在的字段时不会报错
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 使用默认的Jsckson注解
        mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
    }

    public static ObjectMapper getMapper() {
        return mapper;
    }

    public static void setMapper(ObjectMapper mapper) {
        JSONUtil.mapper = mapper;
    }

    public static <T> T parse(String json, Class<T> objectType) {
        if (json == null)
            return null;
        Assert.notNull(objectType, "objectType cannot be null.");
        try {
            return mapper.readValue(json, objectType);
        } catch (IOException e) {
            System.out.println("error:" + json);
            throw new RuntimeException(e);
        }
    }

    public static <T> T parse(InputStream stream, Class<T> objectType) {
        Assert.notNull(stream, "stream cannot be null.");
        Assert.notNull(objectType, "objectType cannot be null.");
        try {
            return mapper.readValue(stream, objectType);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toJson(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static Map<String, Object> toMap(Object obj) {
        String s = toJson(obj);
        HashMap parse = parse(s, HashMap.class);
        return parse;
    }
}
